package com.powernode.shop.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.shop.constant.MenuConstant;
import com.powernode.shop.domain.SysMenu;
import com.powernode.shop.mapper.SysMenuMapper;
import com.powernode.shop.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author ZHAOZHENYU
* @since 2022/10/10
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService{

    @Autowired(required = false)
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public List<SysMenu> loadMenuByUserId(String userId) {

        // 看redis里面有无缓存
        String menuStr = redisTemplate.opsForValue().get(MenuConstant.MENU_PREFIX + userId);
        List<SysMenu> sysMenuList = null;
        if (StringUtils.hasText(menuStr)) {
            sysMenuList = JSON.parseArray(menuStr, SysMenu.class);
        }else {     // redis没有值查数据库
            sysMenuList = sysMenuMapper.findUserMenuList(Long.valueOf(userId));
            // 放入缓存
            if (!CollectionUtils.isEmpty(sysMenuList)){
                redisTemplate.opsForValue().set(MenuConstant.MENU_PREFIX + userId,
                        JSON.toJSONString(sysMenuList), Duration.ofHours(1));
            }
        }
        // 从0开始遍历菜单 得到带结构的菜单
        return formatMenu(sysMenuList,0L);
    }

    /**
     * 递归遍历菜单 得到 分层的菜单集合
     * @param sysMenuList   需要遍历的菜单
     * @param pid   子菜单的父id
     * @return
     */
    public List<SysMenu> formatMenu(List<SysMenu> sysMenuList,Long pid) {

        // 遍历整个菜单取出id与当前pid相等的数据集合放入父菜单 ， 递归传入内部子菜单的id作为下一个的pid
        List<SysMenu> rootMenuList = sysMenuList.stream().filter(sysMenu -> sysMenu.getParentId().equals(pid))
                .collect(Collectors.toList());
        rootMenuList.forEach(r -> r.setList(formatMenu(sysMenuList,r.getMenuId())));

        return rootMenuList;
    }
}
